package shelf

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"github.com/kuangshp/go-utils/k"
	"gorm.io/gorm"
	"insighttracking/apps/admin/auth"
	"insighttracking/apps/admin/internal/svc"
	"insighttracking/apps/admin/internal/types"
	types2 "insighttracking/common/types"
	"insighttracking/query/model"
	"insighttracking/query/service"
	"net/http"

	"github.com/zeromicro/go-zero/core/logx"
	"os"
)

type ApiLogic struct {
	logx.Logger
	ctx     context.Context
	svcCtx  *svc.ServiceContext
	Request *http.Request
}

func NewApiLogic(ctx context.Context, svcCtx *svc.ServiceContext, request *http.Request) *ApiLogic {
	hostname, _ := os.Hostname()
	return &ApiLogic{
		Logger: logx.WithContext(ctx).WithCallerSkip(0).WithFields(
			logx.Field("Log_UUID", uuid.New().String()),
			logx.Field("hostname", hostname)),
		ctx:     ctx,
		svcCtx:  svcCtx,
		Request: request,
	}
}

func (l *ApiLogic) CreateApi(req *types.CreateShelfReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}

	_, err = service.WarehouseAreaService.GetByIdApi(l.ctx, accountInfo.EnterpriseId, req.WarehouseID, req.WarehouseAreaID)
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return "", errors.New("仓库/库区参数有误")
	}

	if req.Code == "" {
		var count int64
		count, err = service.ShelfService.GetCountByWareHouseAreaIdApi(l.ctx, accountInfo.EnterpriseId, req.WarehouseID)
		req.Code = "HJ" + fmt.Sprintf("%04d", count+1)
	}

	if err = service.ShelfService.CreateApi(l.ctx, model.ShelfEntity{
		Name:            req.Name, // 仓库名称
		Code:            req.Code, // 仓库编码
		EnterpriseID:    accountInfo.EnterpriseId,
		WarehouseID:     req.WarehouseID,
		WarehouseAreaID: req.WarehouseAreaID,
	}); err != nil {
		return "", errors.New(err.Error())
	}
	return "操作成功", nil
}

func (l *ApiLogic) DeleteByIdApi(req *types.IdReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	// TODO 判断不能删除的情况

	if err = service.ShelfService.DeleteByIdApi(l.ctx, accountInfo.EnterpriseId, req.Id); err != nil {
		return "", err
	}
	return "操作成功", nil
}

func (l *ApiLogic) GetListApi(req *types.GetShelfListReq) (resp []types2.SimpleList, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return make([]types2.SimpleList, 0), nil
	}
	shelfList, err := service.ShelfService.GetListApi(l.ctx, accountInfo.EnterpriseId, req.WarehouseID, req.WarehouseAreaID, req.Keyword)
	if err != nil {
		return make([]types2.SimpleList, 0), nil
	}
	return k.Map(shelfList, func(item *model.ShelfEntity, index int) types2.SimpleList {
		return types2.SimpleList{
			ID:   item.ID,   // 主键id
			Name: item.Name, // 仓库名称
			Code: item.Code, // 仓库编码
		}
	}), nil
}

func (l *ApiLogic) ModifyByIdApi(req *types.ModifyShelfReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}

	if err = service.ShelfService.ModifyByIdApi(l.ctx, req.Id, accountInfo.EnterpriseId, model.ShelfEntity{
		Name: req.Name, // 仓库名称
		Code: req.Code, // 仓库编码
	}); err != nil {
		return "", err
	}
	return "操作成功", nil
}

func (l *ApiLogic) ModifyDefaultByIdApi(req *types.IdReq) (resp string, err error) {
	accountInfo, err := auth.GetAccountInfo(l.svcCtx, l.Request)
	if err != nil {
		return "", err
	}
	if err = service.ShelfService.ModifyDefaultByIdApi(l.ctx, accountInfo.EnterpriseId, req.Id); err != nil {
		return "", err
	}
	return "操作成功", nil
}

func (l *ApiLogic) ModifyStatusByIdApi(req *types.IdReq) (resp string, err error) {
	if err = service.ShelfService.ModifyStatusByIdApi(l.ctx, req.Id); err != nil {
		return "", err
	}
	return "操作成功", nil
}

func (l *ApiLogic) GetInfoApi(req *types.IdReq) (resp *types.GetShelfInfoResp, err error) {
	resp = &types.GetShelfInfoResp{}
	shelf, err := service.ShelfService.GetSelfByIdApi(l.ctx, req.Id)
	if err != nil {
		return
	}
	resp.Code = shelf.Code
	resp.Name = shelf.Name
	warehouseArea, err := service.WarehouseAreaService.GetByIdApi(l.ctx, shelf.EnterpriseID, shelf.WarehouseID, shelf.WarehouseAreaID)
	if err != nil {
		return
	}
	resp.WarehouseAreaName = warehouseArea.Name
	resp.WarehouseAreaCode = warehouseArea.Code
	warehouse, err := service.WarehouseService.GetWarehouseByIdApi(l.ctx, shelf.EnterpriseID, shelf.WarehouseID)
	if err != nil {
		return
	}
	resp.WarehouseCode = warehouse.Code
	resp.WarehouseName = warehouse.Name
	person, err := service.EnterprisePersonService.GetByIdApi(l.ctx, warehouse.PersonID)
	if err != nil {
		return
	}
	resp.PersonName = person.Name
	return
}
